package com.tianhao.luo.lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用ReentrantLock进行加锁和使用Condition来控制线程间通信
 * 控制间歇打印1和0
 *
 * @author tianhao.luo@hand-china.com
 */
public class ThreadNotifyDemo {

    public static void main(String[] args) {
        Share share = new Share();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "aa").start();


        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "bb").start();


        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "cc").start();


        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "dd").start();
    }


    static class Share {
        /**
         * 初始值
         */
        private int number = 0;

        private ReentrantLock lock = new ReentrantLock();

        private Condition condition = lock.newCondition();


        public void incr() throws InterruptedException {
            lock.lock();
            try {
                // 判断
                while (number != 0) {
                    condition.await();
                }
                number++;
                System.out.println(Thread.currentThread().getName() + ":: " + number);
                // 唤醒
                condition.signalAll();
            } finally {
                lock.unlock();
            }
        }

        public void decr() throws InterruptedException {
            lock.lock();
            try {
                // 判断
                while (number != 1) {
                    condition.await();
                }
                number--;
                System.out.println(Thread.currentThread().getName() + ":: " + number);
                // 唤醒
                condition.signalAll();
            } finally {
                lock.unlock();
            }
        }
    }
}
